package com.lzq.shiro.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.data.redis.core.RedisTemplate;

import com.lzq.shiro.entity.UserInfo;


@SuppressWarnings({"unchecked","rawtypes"})
public class ShiroRedisCache<K , V> implements Cache<K , V>{
	
	private RedisTemplate redisTemplate;
	
	private String prefix = "shiro_authority:";
	
	
	public ShiroRedisCache(RedisTemplate redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	public String getPrefix() {
		return prefix;
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	@Override
	public V get(K k) throws CacheException {
		if(k == null) {
			return null;
		}
		String key = this.getKeyStr(k);
		return (V) redisTemplate.opsForValue().get(key);
	}
	
	// 存储时加上自定义prefix前缀
	@Override
	public V put(K k, V value) throws CacheException {
		System.out.println("前缀：" + this.prefix);
		String key = this.getKeyStr(k);
		if(key != null)
			redisTemplate.opsForValue().set(key, value);
		return value;
	}

	@Override
	public V remove(K k) throws CacheException {
		String key = getKeyStr(k);
		V value = (V) redisTemplate.opsForValue().get(key);
		redisTemplate.delete(key);
		return value;
	}

	@Override
	public void clear() throws CacheException {
		redisTemplate.getConnectionFactory().getConnection().flushDb();
		
	}

	@Override
	public int size() {
		return redisTemplate.getConnectionFactory().getConnection().dbSize().intValue();
	}

	@Override
	public Set<K> keys() {
		Set<K> keys  = redisTemplate.keys(this.prefix + "*");
		Set<K> sets = new HashSet<>();
		for(K key : keys) {
			sets.add(key);
		}
		return sets;
	}

	@Override
	public Collection<V> values() {
		Set<K> keys = keys();
		Collection<V> values = new ArrayList<>();
		for(K key : keys) {
			values.add(get(key));
		}
		return values;
	}
	
	
	public String getKeyStr(K k) {
		if(k != null && k instanceof SimplePrincipalCollection) {
			
			SimplePrincipalCollection principal = (SimplePrincipalCollection) k;
			String key = this.prefix;
			Object obj = principal.getPrimaryPrincipal();
			if(obj instanceof UserInfo) {				
				UserInfo userInfo = (UserInfo) principal.getPrimaryPrincipal();
				key += userInfo.getMobile();
			}else if(obj instanceof String) {
				key += obj;
			}
			return key;
		}
		return null;
	}

}
